package threads;

import java.util.concurrent.*;

/**
 * @author apple
 * @Classname ThreadPoolTest
 * @Description 创建线程池
 * @Date 2020/4/19 16:49
 */
public class ThreadPoolTest {

    public static void main(String[] args) {
        int threadCount = 10;
        int corePoolSize = 4;
        int maximumPoolSize = 8;
        long keepAliveTime = 10;
        TimeUnit timeUnit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>(1);

        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

//        ExecutorService pool = threadPoolCreateWithBlockingQueue(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue ,handler);
//        System.out.println("阻塞队列");
//        try {
//            for (int i = 0; i < threadCount; i++) {
//                ThreadTask threadTask= new ThreadTask();
//                threadTask.setCount(400*(i+1));
//                pool.execute(threadTask);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//
//        System.out.println("有界的任务队列");
//        ArrayBlockingQueue<Runnable> workQueue2 = new ArrayBlockingQueue<Runnable>(3);
//        ExecutorService pool2 = threadPoolCreateWithArrayBlockingQueue(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue2, handler);
//        try {
//            for (int i = 0; i < threadCount; i++) {
//                ThreadTask threadTask= new ThreadTask();
//                threadTask.setCount(500*(i+1));
//                pool2.execute(threadTask);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        System.out.println("无界的任务队列");
//        LinkedBlockingQueue<Runnable> workQueue3 = new LinkedBlockingQueue<Runnable>();
//        ExecutorService pool3= threadPoolCreateWithLinkedBlockingQueue(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue3, handler);
//        try {
//            for (int i = 0; i < threadCount; i++) {
//                ThreadTask threadTask= new ThreadTask();
//                threadTask.setCount(300*(i+1));
//                pool3.execute(threadTask);
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
        System.out.println("优先任务队列");
        PriorityBlockingQueue<Runnable> workQueue4 = new PriorityBlockingQueue<Runnable>();
        ThreadFactory factory=threadFactoryBuilder("优先任务队列");
        ExecutorService pool4 = threadPoolCreateWithPriorityQueue(corePoolSize, maximumPoolSize, keepAliveTime, timeUnit, workQueue4,factory,handler);

        for (int i = 0; i < threadCount; i++) {
            /**优先队列的线程任务**/
            ThreadPriorityTask threadPriorityTask =new ThreadPriorityTask(i);
            threadPriorityTask.setCount(1000*(i+1));
            pool4.execute(threadPriorityTask);
        }

    }

    /**
     * 阻塞队列
     **/
    private static ExecutorService threadPoolCreateWithBlockingQueue(int corePoolSize,
                                                                     int maximumPoolSize,
                                                                     long keepAliveTime,
                                                                     TimeUnit unit,
                                                                     BlockingQueue<Runnable> workQueue,
                                                                     RejectedExecutionHandler handler) {


        ExecutorService pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        return pool;
    }




    /**
     * 有界的任务队列
     **/
    private static ExecutorService threadPoolCreateWithArrayBlockingQueue(int corePoolSize,
                                                                          int maximumPoolSize,
                                                                          long keepAliveTime,
                                                                          TimeUnit unit,
                                                                          ArrayBlockingQueue<Runnable> workQueue,
                                                                          RejectedExecutionHandler handler) {

        ExecutorService pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        return pool;
    }

    /**
     * 无界的任务队列
     **/
    private static ExecutorService threadPoolCreateWithLinkedBlockingQueue(int corePoolSize,
                                                                           int maximumPoolSize,
                                                                           long keepAliveTime,
                                                                           TimeUnit unit,
                                                                           LinkedBlockingQueue<Runnable> workQueue,
                                                                           RejectedExecutionHandler handler) {

        ExecutorService pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
        return pool;
    }

    /**
     * 使用优先队列
     **/
    private static ExecutorService threadPoolCreateWithPriorityQueue(int corePoolSize,
                                                                     int maximumPoolSize,
                                                                     long keepAliveTime,
                                                                     TimeUnit unit,
                                                                     PriorityBlockingQueue<Runnable> workQueue,
                                                                     ThreadFactory factory,
                                                                     RejectedExecutionHandler handler) {
        ExecutorService pool = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,factory, handler);
        return pool;
    }

    /**线程工厂的使用**/
    private static ThreadFactory threadFactoryBuilder(String threadName){
        ThreadFactory threadFactory = new ThreadFactory() {
            @Override
            public Thread newThread(Runnable r) {
                Thread thread =new Thread(r,threadName);
                return thread;
            }
        };
        return threadFactory;
    }
}
